{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "import os\n",
    "# 生成类模型，最终调用的是completions接口，该接口目前已被淘汰，国内代理无法使用\n",
    "from langchain_openai import ChatOpenAI\n",
    "from langchain.schema import HumanMessage, AIMessage, SystemMessage\n",
    "\n",
    "# 国内代理方式，或其它大模型\n",
    "llm = ChatOpenAI(\n",
    "    api_key = \"sk-y7DHfp9fzuCxOVm2158638099f9541D3833aB4F4Ed674aCf\",\n",
    "    base_url = \"https://vip.apiyi.com/v1\",    # 此处代理方式，如果是OpenAI官方接口需调整接口地址\n",
    "    model = \"gpt-4o-mini\",\n",
    "    max_tokens = 1000\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "data": {
      "text/plain": "AIMessage(content='The 2020 World Series was played at Globe Life Field in Arlington, Texas. This was a neutral site due to the COVID-19 pandemic, which affected the regular season and playoff formats.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 40, 'prompt_tokens': 53, 'total_tokens': 93, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}, 'input_tokens': 0, 'output_tokens': 0, 'input_tokens_details': None}, 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_7a53abb7a2', 'id': 'chatcmpl-BkkscNT3BYV4NzjFsXnMUIODyi4el', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--e097b53b-4e54-4fc9-bf9b-a73d0b27aa85-0', usage_metadata={'input_tokens': 53, 'output_tokens': 40, 'total_tokens': 93, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})"
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "messages = [SystemMessage(content=\"You are a helpful assistant.\"),\n",
    " HumanMessage(content=\"Who won the world series in 2020?\"),\n",
    " AIMessage(content=\"The Los Angeles Dodgers won the World Series in 2020.\"),\n",
    " HumanMessage(content=\"Where was it played?\")]\n",
    "\n",
    "llm.invoke(messages)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "prompt=PromptTemplate(input_variables=[], input_types={}, partial_variables={}, template='You are a translation expert, proficient in various languages. \\n\\n    Translates English to Chinese.') additional_kwargs={}\n",
      "prompt=PromptTemplate(input_variables=['text'], input_types={}, partial_variables={}, template='{text}') additional_kwargs={}\n",
      "input_variables=['text'] input_types={} partial_variables={} messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], input_types={}, partial_variables={}, template='You are a translation expert, proficient in various languages. \\n\\n    Translates English to Chinese.'), additional_kwargs={}), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['text'], input_types={}, partial_variables={}, template='{text}'), additional_kwargs={})]\n"
     ]
    }
   ],
   "source": [
    "# 使用System和Human角色的提示模板构造ChatPromptTemplate\n",
    "from langchain.prompts.chat import (\n",
    "    ChatPromptTemplate,\n",
    "    SystemMessagePromptTemplate,\n",
    "    AIMessagePromptTemplate,\n",
    "    HumanMessagePromptTemplate,\n",
    ")\n",
    "\n",
    "# System角色提示词模板\n",
    "template = (\n",
    "    \"\"\"You are a translation expert, proficient in various languages. \\n\n",
    "    Translates English to Chinese.\"\"\"\n",
    ")\n",
    "system_message_prompt = SystemMessagePromptTemplate.from_template(template)\n",
    "print(system_message_prompt)\n",
    "\n",
    "# Human角色提示词模板\n",
    "human_template = \"{text}\"\n",
    "human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)\n",
    "print(human_message_prompt)\n",
    "\n",
    "# 构造ChatPromptTemplate\n",
    "chat_prompt_template = ChatPromptTemplate.from_messages(\n",
    "    [system_message_prompt, human_message_prompt]\n",
    ")\n",
    "print(chat_prompt_template)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "- 规范化 Python 复杂对象\n",
    "- 使用在线工具 [Python Formatter](https://codebeautify.org/python-formatter-beautifier)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [
    {
     "data": {
      "text/plain": "ChatPromptValue(messages=[SystemMessage(content='You are a translation expert, proficient in various languages. \\n\\n    Translates English to Chinese.', additional_kwargs={}, response_metadata={}), HumanMessage(content='I love programming.', additional_kwargs={}, response_metadata={})])"
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 生成用于翻译的 Chat Prompt\n",
    "chat_prompt_template.format_prompt(text=\"I love programming.\")"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [],
   "source": [
    "# 生成聊天模型真正可用的消息记录 Messages\n",
    "chat_prompt = chat_prompt_template.format_prompt(text=\"I love programming.\").to_messages()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [
    {
     "data": {
      "text/plain": "[SystemMessage(content='You are a translation expert, proficient in various languages. \\n\\n    Translates English to Chinese.', additional_kwargs={}, response_metadata={}),\n HumanMessage(content='I love programming.', additional_kwargs={}, response_metadata={})]"
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chat_prompt"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Eason\\AppData\\Local\\Temp\\ipykernel_114272\\3511609987.py:1: LangChainDeprecationWarning: The method `BaseChatModel.__call__` was deprecated in langchain-core 0.1.7 and will be removed in 1.0. Use :meth:`~invoke` instead.\n",
      "  translation_result = llm(chat_prompt)\n"
     ]
    },
    {
     "data": {
      "text/plain": "AIMessage(content='我热爱编程。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 7, 'prompt_tokens': 34, 'total_tokens': 41, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}, 'input_tokens': 0, 'output_tokens': 0, 'input_tokens_details': None}, 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_7a53abb7a2', 'id': 'chatcmpl-Bkn5foqfdpME79WbDZ50GVgReWNJp', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--25b44126-4160-4b05-b045-15affb8c555f-0', usage_metadata={'input_tokens': 34, 'output_tokens': 7, 'total_tokens': 41, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})"
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 直接调用已被弃用，使用invoke\n",
    "translation_result = llm(chat_prompt)\n",
    "translation_result"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "outputs": [
    {
     "data": {
      "text/plain": "AIMessage(content='我喜欢编程。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 6, 'prompt_tokens': 34, 'total_tokens': 40, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}, 'input_tokens': 0, 'output_tokens': 0, 'input_tokens_details': None}, 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_7a53abb7a2', 'id': 'chatcmpl-Bkn67LB3LLoItBg2pEcXS9f5U0E2c', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--b808c00f-4b10-40e2-b122-c3e0b9600950-0', usage_metadata={'input_tokens': 34, 'output_tokens': 6, 'total_tokens': 40, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})"
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "translation_result2 = llm.invoke(chat_prompt)\n",
    "translation_result2"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 使用LLMChain简化重复构造ChatPrompt"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "outputs": [],
   "source": [
    "from langchain.chains import LLMChain\n",
    "\n",
    "# 0.1.17被弃用\n",
    "translation_chain = LLMChain(\n",
    "    llm=llm,\n",
    "    prompt=chat_prompt_template\n",
    ")\n",
    "# translation_chain = chat_prompt_template | llm"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Eason\\AppData\\Local\\Temp\\ipykernel_114272\\1777449283.py:1: LangChainDeprecationWarning: The method `Chain.run` was deprecated in langchain 0.1.0 and will be removed in 1.0. Use :meth:`~invoke` instead.\n",
      "  chain_result = translation_chain.run({'text':\"I love programming.\"})\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我热爱编程。\n"
     ]
    }
   ],
   "source": [
    "chain_result = translation_chain.run({'text':\"I love programming.\"})\n",
    "print(chain_result)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "content='我爱编程。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 6, 'prompt_tokens': 34, 'total_tokens': 40, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}, 'input_tokens': 0, 'output_tokens': 0, 'input_tokens_details': None}, 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_7a53abb7a2', 'id': 'chatcmpl-BknNUFcCMbfHNfWM9RAQ0MH3YsM28', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None} id='run--446d7cee-b574-4e2f-b15b-852cc52ca70e-0' usage_metadata={'input_tokens': 34, 'output_tokens': 6, 'total_tokens': 40, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}\n"
     ]
    }
   ],
   "source": [
    "translation_chain2 = chat_prompt_template | llm\n",
    "chain_result2 = translation_chain2.invoke({'text':\"I love programming.\"})\n",
    "print(chain_result2)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我爱编程。\n"
     ]
    }
   ],
   "source": [
    "print(chain_result2.content)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "outputs": [
    {
     "data": {
      "text/plain": "AIMessage(content='我爱人工智能和大型语言模型。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 10, 'prompt_tokens': 38, 'total_tokens': 48, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}, 'input_tokens': 0, 'output_tokens': 0, 'input_tokens_details': None}, 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_7a53abb7a2', 'id': 'chatcmpl-BknO8HkyyoPHilkZXfaGlMc907btr', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--41663443-db79-43b0-8b37-3bfefae17b50-0', usage_metadata={'input_tokens': 38, 'output_tokens': 10, 'total_tokens': 48, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})"
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "translation_chain2.invoke({'text': \"I love AI and Large Language Model.\"})"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[水果, 颜色, 价格 (美元)] [苹果, 红色, 1.20] [香蕉, 黄色, 0.50] [橙子, 橙色, 0.80] [草莓, 红色, 2.50] [蓝莓, 蓝色, 3.00] [猕猴桃, 绿色, 1.00] [芒果, 橙色, 1.50] [葡萄, 紫色, 2.00]\n"
     ]
    }
   ],
   "source": [
    "res = translation_chain2.invoke({'text': \"[Fruit, Color, Price (USD)] [Apple, Red, 1.20] [Banana, Yellow, 0.50] [Orange, Orange, 0.80] [Strawberry, Red, 2.50] [Blueberry, Blue, 3.00] [Kiwi, Green, 1.00] [Mango, Orange, 1.50] [Grape, Purple, 2.00]\"})\n",
    "print(res.content)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "## 使用System支持多语言翻译"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "outputs": [],
   "source": [
    "# System 增加 source_language 和 target_language\n",
    "template = (\n",
    "    \"\"\"You are a translation expert, proficient in various languages. \\n\n",
    "    Translates {source_language} to {target_language}.\"\"\"\n",
    ")\n",
    "system_message_prompt = SystemMessagePromptTemplate.from_template(template)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "outputs": [],
   "source": [
    "# 待翻译文本由 Human 角色输入\n",
    "human_template = \"{text}\"\n",
    "human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "outputs": [],
   "source": [
    "m_chat_prompt_template = ChatPromptTemplate.from_messages(\n",
    "    [system_message_prompt, human_message_prompt]\n",
    ")"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "outputs": [],
   "source": [
    "translation_chain3 = m_chat_prompt_template | llm"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I enjoy studying large language models; it's easy, simple, and enjoyable.\n"
     ]
    }
   ],
   "source": [
    "res = translation_chain3.invoke({\n",
    "    \"source_language\": \"Chinese\",\n",
    "    \"target_language\": \"English\",\n",
    "    \"text\": \"我喜欢学习大语言模型，轻松简单又愉快\",\n",
    "})\n",
    "print(res.content)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "私は大規模言語モデルを学ぶのが好きです。簡単で楽しく、心地よいです。\n"
     ]
    }
   ],
   "source": [
    "res = translation_chain3.invoke({\n",
    "    \"source_language\": \"Chinese\",\n",
    "    \"target_language\": \"Japanese\",\n",
    "    \"text\": \"我喜欢学习大语言模型，轻松简单又愉快\",\n",
    "})\n",
    "print(res.content)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "langChain",
   "language": "python",
   "name": "langchain"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}